<?php
/**
 * UEShop框架核心文件
 *
 * 每个请求都是从这里开始(相当于前端控制器)
 *
 * ============================================================================
 * 版权所有: (c) 2009-2011，<UEShop Inc>，并保留所有权利。
 * 网站地址: http://www.ueshop.cn
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用；
 * 不允许对程序代码以任何形式任何目的的再发布。
 * ============================================================================
 *
 * @author      cmpan
 * @copyright   Copyright (c) 2009-2011 UEShop Inc. (http://www.ueshop.cn)
 * @license     http://www.ueshop.cn/1_0.txt
 */

defined('UE_IN') or die('Access Denied');

/* 记录程序启动时间 */
define('START_TIME', microtime(true));

// 软件版本信息
define('POWERED',   'UEApp Team'); // 开发者信息
define('SOFTWARE',  'UEApp Engine');        // 软件名称
define('VERSION',   'v1.0 alpha');    // 本程序版本
define('RELEASE',   '20110702');     // 当前UE系统Release
define('COPYRIGHT', '2010-2011 UEApp Team'); // (页头)版权信息

/* 判断请求方式是否是POST */
define('IS_POST', (strtoupper(@$_SERVER['REQUEST_METHOD']) == 'POST'));

/* 判断是否是AJAX请求（是否输出JSON格式数据） */
define('IS_AJAX', !empty($_GET['ajax']));

// 运行环境是否是新浪云平台
define('IS_SEA',  defined('SAE_SECRETKEY') && defined('SAE_ACCESSKEY') && defined('SAE_MYSQL_HOST_M'));

/* 目录常量 */
define('LIBS_DIR',     str_replace('\\', '/' , dirname(__FILE__)));
define('SITE_DIR',     dirname(LIBS_DIR));            // 站的根目录
define('APPS_DIR',     SITE_DIR . '/apps');           // web应用模块的目录

// 载入常用库文件
require_once LIBS_DIR . '/UE/Object.php';
require_once LIBS_DIR . '/UE/Loader.php';
require_once LIBS_DIR . '/UE/Config.php';
require_once LIBS_DIR . '/UE/function.php';
require_once LIBS_DIR . '/UE/Exception.php';
require_once LIBS_DIR . '/UE/Cache/Abstract.php';
require_once LIBS_DIR . '/UE/Lang.php';
require_once LIBS_DIR . '/UE/Model.php';
require_once LIBS_DIR . '/UE/Template.php';
require_once LIBS_DIR . '/UE/Config.php';
require_once LIBS_DIR . '/UE/Paging.php';
require_once LIBS_DIR . '/UE/Controller/Action.php';

require_once LIBS_DIR . '/UE/Session.php';
require_once LIBS_DIR . '/UE/DB.php';
require_once LIBS_DIR . '/UE/Cache.php';

// 必须模型
require_once APPS_DIR . '/system/models/OptionModel.php';
require_once APPS_DIR . '/system/models/AppModel.php';
require_once APPS_DIR . '/system/models/CatModel.php';
require_once APPS_DIR . '/user/models/UserModel.php';

// 自定义错误/异常处理
set_error_handler('errorHandler', E_ALL);
set_exception_handler('exceptionHandler');

// 日志记录
//register_shutdown_function('writeLog');

// 自动加载类库
function __autoload($className) {
	UE_Loader::loadClass($className);
}


define('DATA_WRA',     IS_SEA ? 'saemc://' : '');           //
define('DATA_DIR',     SITE_DIR . '/data');           //
define('TEMP_DIR',     DATA_DIR . '/temp');           // 临时文件目录
define('LANG_DIR',     SITE_DIR . '/languages');      // 语言包目录
define('CACHE_DIR',    DATA_DIR . '/caches');         // 缓存目录
define('UPLOAD_DIR',   SITE_DIR . '/uploads');        // 附件目录
define('THEMES_DIR',   SITE_DIR . '/themes');         // 前台模板风格目录
define('SID_NAME',     cfg('sid_name'));
define('UEID',         makeUeid());

if (!is_file(DATA_DIR . '/install.lock') && !defined('NO_CHECK_INSTALL')){
	header('Location: install');
	exit;
}

// 源码包含目录
@set_include_path('.' . PATH_SEPARATOR . LIBS_DIR);

// 初始化设置
@ini_set('date.timezone',           'Asia/Shanghai');  // 默认时区
@ini_set('memory_limit',            '50M');
@ini_set('session.cache_expire',    180);
@ini_set('session.use_cookies',     true);
@ini_set('magic_quotes_sybase',     false);
@ini_set('magic_quotes_runtime',    false);
@ini_set('session.name',            SID_NAME);  // 不要随意修改
@ini_set('session.use_trans_sid',   0);
@ini_set('session.save_path',       DATA_DIR . '/session');
@ini_set('log_errors',              1);	
@ini_set('error_log',               DATA_DIR .'/logs/phpError.log');
@ini_set('track_errors',            1);

//set_include_path('');
                              
isset($_SERVER['PHP_SELF']) && $_SERVER['PHP_SELF'] = '/' . ltrim($_SERVER['PHP_SELF'], '/');
isset($_SERVER['SCRIPT_NAME']) && $_SERVER['SCRIPT_NAME'] = '/' . ltrim($_SERVER['SCRIPT_NAME'], '/');

// 当前的入口文件名
define('PHP_SELF',     htmlentities(isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : @$_SERVER['SCRIPT_NAME']));

// php5 用短变量名代替这些超级全局变量
unset($HTTP_SERVER_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS);

// 在部分web服务器上会没有REQUEST_URI变量
$queryString = isset($_SERVER['argv']) ? $_SERVER['argv'][0] : $_SERVER['QUERY_STRING'];
if (!isset($_SERVER['REQUEST_URI'])) {	
    $_SERVER['REQUEST_URI'] = PHP_SELF . '?' . $queryString;
} else if (strpos($_SERVER['REQUEST_URI'], '?') === false && $queryString) {
    $_SERVER['REQUEST_URI'] .= '?' . $queryString;
}

empty($_SERVER['HTTP_USER_AGENT']) && $_SERVER['HTTP_USER_AGENT'] = 'unknow';
	
// 分析URL
// Nginx 服务器配置URL Rewrite 规则: rewrite ^/(.+)$ /index.php?$1 last;
if (empty($_GET['app'])) {
	$paramsUrl = UE::url();
	@get_magic_quotes_gpc() && $paramsUrl = addslashes($paramsUrl);
	$params = UE_Url::parse($paramsUrl);
	foreach ($params as $paramKey=>$paramVal) {
		isset($_GET[$paramKey]) || $_GET[$paramKey] = $_REQUEST[$paramKey] = $paramVal;
	}
}

isset($_GET['ctl']) || $_GET['ctl'] = cfg('default_ctl');
isset($_GET['act']) || $_GET['act'] = cfg('default_act');
isset($_GET['id'])  || $_GET['id'] = cfg('default_id');

// 在创建Request实例之前运行,否则将丢掉$_GET的引用
empty($_POST)    || $_POST    = array_map('quotesHttpVars', $_POST);
empty($_GET)     || $_GET     = array_map('quotesHttpVars', $_GET);
empty($_COOKIE)  || $_COOKIE  = array_map('quotesHttpVars', $_COOKIE);
empty($_REQUEST) || $_REQUEST = array_map('quotesHttpVars', $_REQUEST);


// 载入当前用户地区使用的默认的语言包
UE_Lang::getLocale();
UE_Lang::add('common');

// 系统调试模式设置
if (cfg('debug')) {
	error_reporting(E_ALL);
	@ini_set('display_errors', 1);
}
	
// 输出缓冲设置
while(ob_get_level()) {
	@ob_end_clean();
}		
if(cfg('gzipcompress') && function_exists('ob_gzhandler')) {
	@ob_start('ob_gzhandler');
} else { 
    @ob_start();
}

// 解决Flash不能传Cookie
if (!empty($_GET[SID_NAME]) || !empty($_POST[SID_NAME])) {
	session_id(empty($_GET[SID_NAME]) ? $_POST[SID_NAME] : $_GET[SID_NAME]);
}

// session管理
UE_Session::factory()->start();

if (empty($_SESSION['uehash'])) {
	$_SESSION['uehash'] = sprintf('%X', crc32(uniqid()));
}

// 响应头信息
header('X-Powered-By: ' . POWERED);
header('UE-App-Version: ' . VERSION);
header('Content-Type: ' . (IS_AJAX ? 'application/javascript;' : 'text/html;') . ' charset=utf-8');
header('Cache-Control: private, max-age=0, no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);		
header('Pragma: no-cache');

/**
 * 核心
 *
 */
final class UE {	
	private static $_ctx    = '';
	private static $_site   = '';
	private static $_base   = '';
	
	private static $_theme  = null;
	
	/**
	 * 系统配置信息
	 *
	 * @var array
	 */
	private static $_etc = array('apps'=>array(), 'acts'=>array(), 'acls'=>array(), 'grps'=>array(),);
	
	/**
	 * 系统从这里开始正式运行
	 *
	 * @param string $confFile 系统配置文件
	 */
	public static function boot() {	
		/* 过滤器 */
		$filters = $filterObjs = array();
		$filtersFile = DATA_DIR . '/system/flts.php';
		if (is_file($filtersFile)) {
			$filters = include $filtersFile;
		}

		$filters[] = array('class' => 'AuthFilter', 'app' => 'user');
		$filterErrs = array();	
		// $filter = array('class', 'app');
		foreach ($filters as $filter) {
			if (!UE_Loader::loadFilter($filter['class'], $filter['app'])) {
				continue;
			}
			
			$filterObjs[$filter['class']] = new $filter['class'];
			if(!$filterObjs[$filter['class']]->before()) {
				foreach((array)$filterObjs[$filter['class']]->getErrs() as $e) {
					$filterErrs[] = $e;
				}
			}
		}
		/* End 过滤器 */

		$app         = lcfirst($_GET['app']); // Action控制器
		$ctlCls      = ucfirst($_GET['ctl']) . 'Controller';
		$actFnc      = lcfirst($_GET['act']) . 'Action';		
		$ctlFile     = APPS_DIR . "/{$app}/controllers/{$ctlCls}.php";
		
		if (!is_file($ctlFile)) {
			//UE_Header::setStatus(404);
			throw new UE_Exception("controller file (apps/$app/controllers/$ctlCls.php) not exists");
		}
		
		require_once $ctlFile;
		
		if(!class_exists($ctlCls, false)) {			
			//UE_Header::setStatus(404);
		    throw new UE_Exception( "controller class ($ctlCls) not exists");		   
		}
		
		$actionController = new $ctlCls();
		
		if(!method_exists ($actionController, $actFnc)) { 
			//UE_Header::setStatus(404);
	        throw new UE_Exception("action($actFnc) not exists");		    
		}
		
		if($filterErrs) {
			$actionController->setErr($filterErrs);
		}
		
		method_exists($actionController, 'init') && $actionController->init();
		$actionController->$actFnc();
		
		foreach ($filterObjs as $filterObj) {
			$filterObj->after();
		}		
	}
	
	/**
	 * 当前网站地址
	 * example: http://xx.xx.xx
	 *
	 * @return string 当前网站地址 http://xx.xx.xx:8080
	 */
	public static function site() {
		if(self::$_site) {
			return self::$_site;
		}

		/* 协议, http|https */
		$protocol = (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) ? 'https://' : 'http://';
		/* 域名或IP地址 */
		if(isset($_SERVER['HTTP_HOST'])) {
			$host = $_SERVER['HTTP_HOST'];
		} elseif(isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
			$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
		} else {
			/* 端口 */
			if(isset($_SERVER['SERVER_PORT'])) {
				$port = ':' . $_SERVER['SERVER_PORT'];
				if((':80' == $port && 'http://' == $protocol) || (':443' == $port &&
						 'https://' == $protocol)) {
					$port = '';
				}
			} else {
				$port = '';
			}
			
			if(isset($_SERVER['SERVER_NAME'])) {
				$host = $_SERVER['SERVER_NAME'] . $port;
			} elseif(isset($_SERVER['SERVER_ADDR'])) {
				$host = $_SERVER['SERVER_ADDR'] . $port;
			}
		}
		isset($host) || $host = 'localhost';
		return self::$_site = $protocol . $host;
	}
	
	/**
	 * 网站请求url前面部分
	 *
	 * @return string
	 */
	public static function base() {
		if(self::$_base) {
			return self::$_base;
		}

		self::$_base = (cfg('rewrite') ? self::context() : PHP_SELF . '?');
		
		if(cfg('full_url')) {
			self::$_base = self::site() . self::$_base;
		}
		
		return self::$_base;
	}
		
	/**
	 * 当期web上下文的URL
	 * example: http://www.mjie.net/xx/ 的上下文为 /xx/
	 *
	 * @return string
	 */
	public static function context() {
		if(self::$_ctx) {
			return self::$_ctx;
		}
		$context = substr(PHP_SELF, 0, strrpos(PHP_SELF, "/"));
		$context = rtrim($context, '/') . '/';
		
		return self::$_ctx = htmlspecialchars($context);
	}
	
	
	/**
	 * 获取服务器主机名
	 *
	 * @return string
	 */
	public static function host() {
		$host = 'localhost';
		
		if(isset($_SERVER['HTTP_HOST'])) {
			$host = $_SERVER['HTTP_HOST'];
		} else if(isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
			$host = $_SERVER['HTTP_X_FORWARDED_HOST'];
		}
		
		return $host;
	}
		
	/**
	 * 链接到当前页面的前一页面(来源页)的 URL 地址
	 *
	 * @return string
	 */
	public static function referer() {
		return empty($_SERVER['HTTP_REFERER']) ? self::site() : $_SERVER['HTTP_REFERER'];
	}
	
    /**
	 * 获取当前请求的url
	 * 网站域名或所在目录有可能改变，故不要将该返回数据持久化
	 *
	 * @return string
	 */
	public static function url() {
		return  self::site() . $_SERVER['REQUEST_URI'];
	}
	
		
    /**
	 * 获取当前请求的编码后的url
	 * 网站域名或所在目录有可能改变，故不要将该返回数据持久化
	 *
	 * @return string
	 */
	public static function urlEncoded() {
		return  UE_Encoder::encode(self::site() . $_SERVER['REQUEST_URI']);
	}
	
	
						
	/**
	 * 获取系统配置信息
	 * $name = apps|acts|acls|grps
	 * apps: 应用程序模块信息
	 * acts: 全站服务功能列表
	 * acls: 权限控制列表
	 * grps: 用户组配置信息
	 *
	 * @param string $name 系统配置信息变量: apps|acts|acls|grps
	 * @param bool $reset 是否重置系统配置变量
	 * @return array
	 */
	public static function getEtc($name = '', $reset = false) {
		return ;
		if (!$name) {
			return self::$_etc;
		}
		
		if (!self::$_etc[$name] || $reset) {			
			if ($reset || !(self::$_etc[$name] = UE_Cache::factory()->get('etc/'.$name))) {
				// 获取配置信息
				if ($name == 'grps') {
					UE_Loader::loadModel('UserGroupModel', 'user');
					$group = new UserGroupModel();
					self::$_etc[$name] = $group->getGroups();
				} else {					
				    self::$_etc[$name] = OptionsModel::getOption(strtoupper('etc_'.$name), $reset);
				    self::$_etc[$name] = unserialize(self::$_etc[$name]);
				}
				
				// 设置配置信息缓存
				UE_Cache::factory()->set('etc/' .$name, self::$_etc[$name], 99999);
			}
		}
		
		return self::$_etc[$name];	
	}
	
	public static function setTheme($theme) {
		self::$_theme = $_SESSION['my_theme'] = $theme;
	}
	
	/**
	 * 获取风格
	 * 
	 * @todo 动态获取风格
	 * @return string
	 */
	public static function getTheme() {		
		if (!empty($_GET['set_theme_by_uri']) && is_dir(THEMES_DIR . '/' . $_GET['set_theme_by_uri'])) {
			self::setTheme($_GET['set_theme_by_uri']);
			$_SESSION['my_theme'] = $_GET['set_theme_by_uri'];
		}
		
		if (self::$_theme) {
			return self::$_theme;
		}
		
		if (!empty($_SESSION['my_theme'])) {
			return self::$_theme = $_SESSION['my_theme'];
		}
		
		return self::$_theme = cfg('theme');
	}
	
	public static function loadUserInfo() {
		$_SESSION['user_id'] = 0;
	}
	
}

